use clap::Parser;
use once_cell::sync::Lazy;
use crate::util::probe_interface_ip;

// Setup the command line interface with clap.
#[derive(Parser, Debug, Clone)]
#[clap(name = "server", about = "Hoi's Weak Network Emulator Server!")]
pub struct Opt {
    /// set the log level
    #[clap(short = 'l', long = "log", default_value = "debug")]
    pub log_level: String,

    /// set the listen addr
    #[clap(short = 'a', long = "addr", default_value = "0.0.0.0")]
    pub addr: String,

    /// set the listen port
    #[clap(long = "web-port", default_value = "8080")]
    pub web_port: u16,

    /// set the public addr
    #[clap(long = "announce-ip", default_value = "")]
    pub announce_ip: String,

    /// set the directory where static files are to be found
    #[clap(long = "static-dir", default_value = "../dist")]
    pub static_dir: String,

    /// set the directory for temporary trace files
    #[clap(short = 'd', long = "dir", default_value = "/tmp")]
    pub tmp_dir: String,

    /// set the server tcp port
    #[clap(long = "server-name", default_value = "server")]
    pub server_name: String,
    
    /// set the server tcp port
    #[clap(long = "server-tcp-port", action = clap::ArgAction::Append)]
    pub server_tcp_port: Vec<u16>,

    /// set the server udp port
    #[clap(long = "server-udp-port", action = clap::ArgAction::Append)]
    pub server_udp_port: Vec<u16>,
    
    /// user command
    #[clap(last = true)]
    pub user_cmd: Vec<String>,
}

pub static OPTS: Lazy<Opt> = Lazy::new(|| {
    println!("parse opts");
    let mut opt = Opt::parse();
    if opt.announce_ip.is_empty() {
        let (_, ip) = probe_interface_ip();
        opt.announce_ip = ip.to_string();
    }
    if opt.user_cmd.is_empty() {
        opt.user_cmd.push("echo".into());
        opt.user_cmd.push("-n".into());
    }
    opt
});

impl Opt {
    pub fn build_user_cmd(&self) -> String {
        format!("sh -c \"{}\"", self.user_cmd.join(" "))
    }
}
